/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.user.rest;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import co.yixiang.api.ApiResult;
import co.yixiang.api.YshopException;
import co.yixiang.common.aop.NoRepeatSubmit;
import co.yixiang.common.bean.LocalUser;
import co.yixiang.common.interceptor.AuthCheck;
import co.yixiang.constant.ShopConstants;
import co.yixiang.enums.*;
import co.yixiang.modules.auction.domain.*;
import co.yixiang.modules.auction.service.*;
import co.yixiang.modules.auction.service.dto.UserGoodsDto;
import co.yixiang.modules.auction.service.mapper.AuctionProductMapper;
import co.yixiang.modules.auction.service.mapper.YxAuctionMemberMapper;
import co.yixiang.modules.auction.service.mapper.YxAuctionOrderMapper;
import co.yixiang.modules.auction.service.mapper.YxAuctionProductMapper;
import co.yixiang.modules.commom.domain.YxAppdict;
import co.yixiang.modules.commom.service.YxAppdictService;
import co.yixiang.modules.order.service.YxStoreOrderService;
import co.yixiang.modules.order.vo.UserOrderCountVo;
import co.yixiang.modules.pay.AppPayService;
import co.yixiang.modules.product.service.YxStoreProductRelationService;
import co.yixiang.modules.product.vo.YxStoreProductRelationQueryVo;
import co.yixiang.modules.shop.service.YxSystemGroupDataService;
import co.yixiang.modules.user.domain.*;
import co.yixiang.modules.user.param.UserEditParam;
import co.yixiang.modules.user.param.WeixinParam;
import co.yixiang.modules.user.param.ZhifubaoParam;
import co.yixiang.modules.user.service.*;
import co.yixiang.modules.user.service.dto.*;
import co.yixiang.modules.user.service.mapper.YxDistributorRelationMapper;
import co.yixiang.modules.user.vo.SignVo;
import co.yixiang.modules.user.vo.YxUserQueryVo;
import co.yixiang.mp.service.WeixinPayService;
import co.yixiang.utils.RandonOrderNoUtil;
import co.yixiang.utils.RedisUtils;
import co.yixiang.utils.StringUtils;
import co.yixiang.utils.VerifyUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 用户控制器
 * </p>
 *
 * @author hupeng
 * @since 2019-10-16
 */
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(value = "用户中心", tags = "用户:用户中心", description = "用户中心")
public class UserController {

    private final YxUserService yxUserService;
    private final YxSystemGroupDataService systemGroupDataService;
    private final YxStoreOrderService orderService;
    private final YxStoreProductRelationService relationService;
    private final YxUserSignService userSignService;
    private final YxUserBillService userBillService;
    private final YxUserinfoService yxUserinfoService;
    private final YxAuctionOrderMapper yxAuctionOrderMapper;
    private final YxUserBankService yxUserBankService;
    private final YxAuctionLevelService auctionLevelService;
    private final AuctionRecordService auctionRecordService;
    private final YxDistributorRelationMapper distributorRelationMapper;
    private final AuctionProductMapper auctionProductMapper;
    private final YxUserGoodsService userGoodsService;
    private final RedisUtils redisUtil;
    private final YxAuctionMemberService auctionMemberService;
    private final YxAuctionMemberMapper auctionMemberMapper;
    private final YxAppdictService yxAppdictService;
    private final YxAuthenticationService authenticationService;
    private final YxUserViolateLogService userViolateLogService;
    private final WeixinPayService weixinPayService;



    /**
     * 用户资料
     */
    @AuthCheck
    @GetMapping("/userinfo")
    @ApiOperation(value = "获取用户信息",notes = "获取用户信息",response = YxUserQueryVo.class)
    public ApiResult<Object> userInfo(){
        YxUser yxUser = LocalUser.getUser();
        return ApiResult.ok(yxUserService.getNewYxUserById(yxUser));
    }


    @GetMapping("/memberList")
    @ApiOperation(value = "会员套餐列表",notes = "会员套餐列表")
    public ApiResult<Object> memberList(){
        List<YxAuctionMember> list = auctionMemberService.list(new QueryWrapper<YxAuctionMember>().lambda()
                .orderByAsc(YxAuctionMember::getCreateTime));
        return ApiResult.ok(list);
    }

    @AuthCheck
    @NoRepeatSubmit
    @GetMapping("/openMember")
    @ApiOperation(value = "开通会员",notes = "开通会员")
    public ApiResult openMember(@RequestParam(value = "id" ,required = false) Integer id,
                                @RequestParam(value = "payType" ,required = false) Integer payType ,
                                @RequestParam(value = "payImage" ,required = false) String payImage ,
                                HttpServletRequest request ){
        YxUser yxUser = LocalUser.getUser();
        YxAuctionMember auctionMember = auctionMemberService.getById(id);
        if (ObjectUtil.isEmpty(auctionMember)) throw new YshopException("当前会员套餐不存在");

        String orderNo = "openMember"+RandonOrderNoUtil.getOrderIdByTime();

        //积分流水入库
        YxUserBill userBill = YxUserBill.builder()
                .uid(yxUser.getUid())
                .title("开通会员")
                .linkId(auctionMember.getId().toString())
                .category(BillDetailEnum.CATEGORY_5.getValue())
                .type(BillDetailEnum.TYPE_14.getValue())
                .status(BillEnum.STATUS_0.getValue())
                .number(auctionMember.getPrice())
                .balance(yxUser.getNowMoney())
                .mark("开通会员")
                .payType(payType)
                .payImage(payImage)
                .orderNo(orderNo)
                .pm(BillEnum.PM_0.getValue())
                .build();
        userBillService.save(userBill);


        return ApiResult.ok(200 , "开通会员申请中");

//        return ApiResult.ok(appPayService.payment(request ,payType ,orderNo ,auctionMember.getPrice()));
    }


    @AuthCheck
    @NoRepeatSubmit
    @GetMapping("/appletOpenMember")
    @ApiOperation(value = "小程序开通会员",notes = "小程序开通会员")
    public ApiResult appletOpenMember(@RequestParam(value = "id" ,required = false) Integer id,
                                HttpServletRequest request ){
        YxUser yxUser = LocalUser.getUser();
        YxAuctionMember auctionMember = auctionMemberService.getById(id);
        if (ObjectUtil.isEmpty(auctionMember)) throw new YshopException("当前会员套餐不存在");

        String orderNo = "openMember"+RandonOrderNoUtil.getOrderIdByTime();

        //积分流水入库
        YxUserBill userBill = YxUserBill.builder()
                .uid(yxUser.getUid())
                .title("开通会员")
                .linkId(auctionMember.getId().toString())
                .category(BillDetailEnum.CATEGORY_5.getValue())
                .type(BillDetailEnum.TYPE_14.getValue())
                .status(BillEnum.STATUS_0.getValue())
                .number(auctionMember.getPrice())
                .balance(yxUser.getNowMoney())
                .mark("开通会员")
                .payType(2)
                .orderNo(orderNo)
                .pm(BillEnum.PM_0.getValue())
                .build();
        userBillService.save(userBill);

        Map<String,String> jsConfig = new HashMap<>();
        WxPayMpOrderResult wxPayMpOrderResult = (WxPayMpOrderResult)weixinPayService
                .unifyPay(orderNo,"routine", BillDetailEnum.TYPE_14.getValue(),"小程序充值");
        jsConfig.put("appId",wxPayMpOrderResult.getAppId());
        jsConfig.put("timeStamp",wxPayMpOrderResult.getTimeStamp());
        jsConfig.put("paySign",wxPayMpOrderResult.getPaySign());
        jsConfig.put("nonceStr",wxPayMpOrderResult.getNonceStr());
        jsConfig.put("package",wxPayMpOrderResult.getPackageValue());
        jsConfig.put("signType",wxPayMpOrderResult.getSignType());

        return ApiResult.ok(jsConfig);
    }

    @AuthCheck
    @GetMapping("/openMemberLog")
    @ApiOperation(value = "开通会员记录",notes = "开通会员记录")
    public ApiResult openMemberLog(){
        YxUser user = LocalUser.getUser();
        return ApiResult.ok(auctionMemberMapper.openMemberLog(user.getUid()));
    }


    @AuthCheck
    @GetMapping("/violateLog")
    @ApiOperation(value = "违规记录",notes = "违规记录")
    public ApiResult violateLog(){
        YxUser user = LocalUser.getUser();
        List<YxUserViolateLog> list = userViolateLogService.list(new QueryWrapper<YxUserViolateLog>().lambda()
                .eq(YxUserViolateLog::getUid, user.getUid())
                .orderByDesc(YxUserViolateLog::getViolateTime));
        return ApiResult.ok(list);
    }

    /**
     * 新手教程
     */
    @GetMapping("/newPeople")
    @ApiOperation(value = "新手教程",notes = "新手教程")
    public ApiResult<Object> newPeople(){
        return ApiResult.ok(yxAuctionOrderMapper.getNewPeople());
    }



    /**
     * 获取可用余额
     */
    @AuthCheck
    @GetMapping("/ablePrice")
    @ApiOperation(value = "获取可用余额",notes = "获取可用余额")
    public ApiResult ablePrice(){
        YxUser yxUser = LocalUser.getUser();
        BigDecimal yp = yxAuctionOrderMapper.selectTodayPriceByUid(yxUser.getUid());
        BigDecimal kp = auctionLevelService.getOne(new LambdaQueryWrapper<YxAuctionLevel>().eq(YxAuctionLevel::getLevel,yxUser.getHighestLevel())).getBidAmount().add(yxUser.getAuctionAmount());
        return ApiResult.ok(kp.subtract(yp));
    }

    /**
     * 获取个人中心菜单
     */
    @GetMapping("/menu/user")
    @ApiOperation(value = "获取个人中心菜单",notes = "获取个人中心菜单")
    public ApiResult<Map<String,Object>> userMenu(){
        Map<String,Object> map = new LinkedHashMap<>();
        map.put("routine_my_menus",systemGroupDataService.getDatas(ShopConstants.YSHOP_MY_MENUES));
        return ApiResult.ok(map);
    }



    /**
     * 订单统计数据
     */
    @AuthCheck
    @GetMapping("/order/data")
    @ApiOperation(value = "订单统计数据",notes = "订单统计数据")
    public ApiResult<UserOrderCountVo> orderData(){
        Long uid = LocalUser.getUser().getUid();
        return ApiResult.ok(orderService.orderData(uid));
    }

    /**
     * 获取收藏产品
     */
    @AuthCheck
    @GetMapping("/collect/user")
    @ApiOperation(value = "获取收藏产品",notes = "获取收藏产品")
    public ApiResult<List<YxStoreProductRelationQueryVo>> collectUser(@RequestParam(value = "page",defaultValue = "1") int page,
                                                                      @RequestParam(value = "limit",defaultValue = "10") int limit){
        Long uid = LocalUser.getUser().getUid();
        return ApiResult.ok(relationService.userCollectProduct(page,limit,uid));
    }

    /**
     * 用户资金统计
     */
    @AuthCheck
    @GetMapping("/user/balance")
    @ApiOperation(value = "用户资金统计",notes = "用户资金统计")
    public ApiResult<Object> userBalance(){
        YxUser yxUser = LocalUser.getUser();
        Map<String,Object> map = Maps.newHashMap();
        Double[] userMoneys = yxUserService.getUserMoney(yxUser.getUid());
        map.put("now_money",yxUser.getNowMoney());
        map.put("orderStatusSum",userMoneys[0]);
        map.put("recharge",userMoneys[1]);
        return ApiResult.ok(map);
    }


    /**
     * 签到用户信息
     */
    @AuthCheck
    @PostMapping("/sign/user")
    @ApiOperation(value = "签到用户信息",notes = "签到用户信息")
    public ApiResult<YxUserQueryVo> sign(){
        YxUser yxUser = LocalUser.getUser();
        return ApiResult.ok(userSignService.userSignInfo(yxUser));
    }

    /**
     * 签到配置
     */
    @GetMapping("/sign/config")
    @ApiOperation(value = "签到配置",notes = "签到配置")
    public ApiResult<Object> signConfig(){
        return ApiResult.ok(systemGroupDataService.getDatas(ShopConstants.YSHOP_SIGN_DAY_NUM));
    }

    /**
     * 签到列表
     */
    @AuthCheck
    @GetMapping("/sign/list")
    @ApiOperation(value = "签到列表",notes = "签到列表")
    public ApiResult<List<SignVo>> signList(@RequestParam(value = "page",defaultValue = "1") int page,
                                            @RequestParam(value = "limit",defaultValue = "10") int limit){
        Long uid = LocalUser.getUser().getUid();
        return ApiResult.ok(userSignService.getSignList(uid,page,limit));
    }

    /**
     * 签到列表（年月）
     */
    @AuthCheck
    @GetMapping("/sign/month")
    @ApiOperation(value = "签到列表（年月）",notes = "签到列表（年月）")
    public ApiResult<Object> signMonthList(@RequestParam(value = "page",defaultValue = "1") int page,
                                           @RequestParam(value = "limit",defaultValue = "10") int limit){
        Long uid = LocalUser.getUser().getUid();
        return ApiResult.ok(userBillService.getUserBillList(page, limit,uid, BillInfoEnum.SIGN_INTEGRAL.getValue()));
    }

    /**
     * 开始签到
     */
    @NoRepeatSubmit
    @AuthCheck
    @PostMapping("/sign/integral")
    @ApiOperation(value = "开始签到",notes = "开始签到")
    public ApiResult<Object> signIntegral(){
        YxUser yxUser = LocalUser.getUser();
        int integral = userSignService.sign(yxUser);;

        Map<String,Object> map = new LinkedHashMap<>();
        map.put("integral",integral);
        return ApiResult.ok(map,"签到获得" + integral + "积分");
    }


    @AuthCheck
    @PostMapping("/user/edit")
    @ApiOperation(value = "用户修改信息",notes = "用修改信息")
    public ApiResult<Object> edit(@Validated @RequestBody UserEditParam param){
        YxUser yxUser = LocalUser.getUser();
        if(null !=param.getAvatar() && !"".equals(param.getAvatar())){
            yxUser.setAvatar(param.getAvatar());
        }
        if(null !=param.getNickname() && !"".equals(param.getNickname())){
            yxUser.setNickname(param.getNickname());
        }
        if(null !=param.getUserBirthday() && !"".equals(param.getUserBirthday())){
            yxUser.setUserBirthday(param.getUserBirthday());
        }
        if(null !=param.getIsPush()){
            yxUser.setIsPush(param.getIsPush());
        }
        yxUserService.updateById(yxUser);

        return ApiResult.ok("修改成功");
    }

    @AuthCheck
    @NoRepeatSubmit
    @PostMapping("/updateZFbAccount")
    @ApiOperation(value = "用户绑定支付宝",notes = "用户绑定支付宝")
    public ApiResult updateZFbAccount(@Validated @RequestBody ZhifubaoParam param){
        YxUser yxUser = LocalUser.getUser();
        Object codeObj = redisUtil.get("code_" + yxUser.getPhone());
        if(codeObj == null){
            return ApiResult.fail("请先获取验证码");
        }
        String code = codeObj.toString();
        if (!StrUtil.equals(code, param.getCode())) {
            return ApiResult.fail("验证码错误");
        }
        YxUserinfo yxUserinfo=yxUserinfoService.selectByUserId(yxUser.getUid());
        if(null !=yxUserinfo){
                yxUserinfo.setZhifubaoAccount(param.getZhifubaoAccount());
                yxUserinfo.setZhifubaoCode(param.getZhifubaoCode());
                yxUserinfo.setZhifubaoName(param.getZhifubaoName());
                yxUserinfo.setBindZfb(1);
                yxUserinfoService.updateById(yxUserinfo);
        }
        redisUtil.del("code_" + yxUser.getPhone());
        return ApiResult.ok("修改成功");
    }

    @AuthCheck
    @NoRepeatSubmit
    @PostMapping("/updateWXAccount")
    @ApiOperation(value = "用户绑定微信",notes = "用户绑定微信")
    public ApiResult updateWXAccount(@Validated @RequestBody WeixinParam param){
        YxUser yxUser = LocalUser.getUser();
        Object codeObj = redisUtil.get("code_" + yxUser.getPhone());
        if(codeObj == null){
            return ApiResult.fail("请先获取验证码");
        }
        String code = codeObj.toString();
        if (!StrUtil.equals(code, param.getCode())) {
            return ApiResult.fail("验证码错误");
        }
        YxUserinfo yxUserinfo=yxUserinfoService.selectByUserId(yxUser.getUid());
        if(null !=yxUserinfo){
            yxUserinfo.setWeixinAccount(param.getWeixinAccount());
            yxUserinfo.setWeixinCode(param.getWeixinCode());
            yxUserinfo.setWeixinName(param.getWeixinName());
            yxUserinfo.setBindWx(1);
            yxUserinfoService.updateById(yxUserinfo);
        }
        redisUtil.del("code_" + yxUser.getPhone());
        return ApiResult.ok("修改成功");
    }

    @AuthCheck
    @NoRepeatSubmit
    @PostMapping("/bindBank")
    @ApiOperation(value = "用户绑定银行卡号",notes = "用户绑定银行卡号")
    public ApiResult bindBank(@Validated @RequestBody YxUserBankDto param){
        YxUser yxUser = LocalUser.getUser();
        Object codeObj = redisUtil.get("code_" + yxUser.getPhone());
        if(codeObj == null){
            return ApiResult.fail("请先获取验证码");
        }
        String code = codeObj.toString();
        if (!StrUtil.equals(code, param.getCode())) {
            return ApiResult.fail("验证码错误");
        }
        YxAuthentication authentication = authenticationService.getOne(new QueryWrapper<YxAuthentication>().lambda()
                .eq(YxAuthentication::getUid, yxUser.getUid()));
        if (ObjectUtil.isEmpty(authentication)) throw new YshopException("请先认证再绑定银行卡号！");
        //判断银行卡4元素是否正确
//        try {
//            String url = "http://v.juhe.cn/verifybankcard4/query?key=510dd1cbc01ea55285e1da9b4891badb&realname=REALNAME&bankcard=BANKCARD&idcard=IDCARD&mobile=MOBILE";
//            url = url.replace("REALNAME" , authentication.getRealName());
//            url = url.replace("BANKCARD" , param.getBankNumber());
//            url = url.replace("IDCARD" , authentication.getCardNumber());
//            url = url.replace("MOBILE" , yxUser.getPhone());
//            Map<String, Object> map = VerifyUtil.sendGet(url);
//
//            //            Map<String, Object> map = VerifyUtil.sendGet("http://v.juhe.cn/verifybankcard3/query?key=510dd1cbc01ea55285e1da9b4891badb&realname=" + authentication.getRealName() + "&bankcard=" + param.getBankNumber() + "&idcard=" + authentication.getCardNumber() + "&mobile=" + yxUser.getPhone());
//            String entity = String.valueOf(map.get("entity"));
//            JSONObject jsonObject = JSONObject.parseObject(entity);
//            if (!jsonObject.getString("error_code").equals("0")){
//                return ApiResult.fail(jsonObject.getString("reason"));
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        param.setUid(yxUser.getUid());
        YxUserBank yxUserBank=new YxUserBank();
        BeanUtils.copyProperties(param,yxUserBank);
        YxUserinfo yxUserinfo=yxUserinfoService.selectByUserId(yxUser.getUid());
        if(null !=yxUserinfo){
            yxUserinfo.setBindBank(1);
            yxUserinfoService.updateById(yxUserinfo);
        }
        YxUserBank one = yxUserBankService.getOne(new QueryWrapper<YxUserBank>().lambda()
                .eq(YxUserBank::getUid, yxUser.getUid()));
        if (ObjectUtil.isNotEmpty(one)) yxUserBankService.removeById(one);
        yxUserBankService.save(yxUserBank);

        redisUtil.del("code_" + yxUser.getPhone());
        return ApiResult.ok("绑定成功");
    }




    @AuthCheck
    @PostMapping("/user/setPayPassword")
    @ApiOperation(value = "设置支付密码",notes = "设置支付密码")
    public ApiResult<Object> setPayPassword(@Validated @RequestBody AppLoginRequest appLoginRequest){
        YxUser yxUser = LocalUser.getUser();
        appLoginRequest.setUserId(yxUser.getUid());
        return yxUserService.setPayPassword(appLoginRequest);
    }

    @AuthCheck
    @GetMapping("/user/fansNum")
    @ApiOperation(value = "我的粉丝数量",notes = "我的粉丝数量")
    public ApiResult fansNum(){
        YxUser user = LocalUser.getUser();
        Map<String , Object> map = new HashMap<>();
        //直推数
        /*int count = distributorRelationMapper.selectCount(new QueryWrapper<YxDistributorRelation>().lambda()
                .eq(YxDistributorRelation::getPUid, user.getUid()));*/
        int count = distributorRelationMapper.getSelectCount(user.getUid());
        map.put("oneFans" , count);
        //间推数
        int count2 = distributorRelationMapper.selectTwoNum(user.getUid());
        map.put("twoFans" , count2);
        //团队数
        Integer count3 = getFansNum(String.valueOf(user.getUid())).size();
        map.put("threeFans" , count3);
        return ApiResult.ok(map);
    }


    @AuthCheck
    @GetMapping("/user/fansList")
    @ApiOperation(value = "我的粉丝列表",notes = "我的粉丝列表")
    public ApiResult fansList(@RequestParam(value = "type" ,defaultValue = "1") Integer type,
                              @RequestParam(value = "page" ,defaultValue = "1") Integer page,
                              @RequestParam(value = "limit" ,defaultValue = "10") Integer limit){
        YxUser user = LocalUser.getUser();
        Page<FansListDto> pageModel = new Page<>(page, limit);
        IPage<FansListDto> listDtoIPage ;
        if(type == 1){
            listDtoIPage = distributorRelationMapper.fansList1(pageModel , user.getUid());
        }else {
            listDtoIPage = distributorRelationMapper.fansList2(pageModel , user.getUid());
        }
        for (FansListDto listDto: listDtoIPage.getRecords()) {
            //队员数
            listDto.setFansNum(getFansNum(String.valueOf(listDto.getUid())).size());
            /*//是否是有效用户
            int count = authenticationService.count(new QueryWrapper<YxAuthentication>().lambda()
                    .eq(YxAuthentication::getUid, listDto.getUid())
                    .eq(YxAuthentication::getStatus, 1));
            if (count > 0 && listDto.getNowMoney().compareTo(new BigDecimal("200")) > -1) {
                listDto.setIsAble(1);
            }*/
        }
        return ApiResult.ok(listDtoIPage);
    }


    @AuthCheck
    @GetMapping("/user/billDetails")
    @ApiOperation(value = "余额明细",notes = "余额明细")
    public ApiResult billDetails(@RequestParam(value = "page" ,defaultValue = "1") Integer page,
                                 @RequestParam(value = "limit" ,defaultValue = "10") Integer limit){
        YxUser user = LocalUser.getUser();
        Page<BillDetail> pageModel = new Page<>(page, limit);
        IPage<BillDetail> listDtoIPage = distributorRelationMapper.billDetails(pageModel , user.getUid());
        return ApiResult.ok(listDtoIPage);
    }

    @AuthCheck
    @GetMapping("/user/brokeragePrice")
    @ApiOperation(value = "佣金",notes = "佣金")
    public ApiResult brokeragePrice(@RequestParam(value = "type" ,defaultValue = "1") Integer type){
        YxUser user = LocalUser.getUser();
        return ApiResult.ok(distributorRelationMapper.brokeragePrice(user.getUid() , type));
    }

    @AuthCheck
    @GetMapping("/user/nowBrokeragePrice")
    @ApiOperation(value = "今日佣金",notes = "今日佣金")
    public ApiResult nowBrokeragePrice(){
        YxUser user = LocalUser.getUser();
        Map<String , BigDecimal> nowBrokeragePrice = new HashMap<>();
        nowBrokeragePrice.put("b1" , distributorRelationMapper.getB3ByUid(user.getUid()));
        nowBrokeragePrice.put("b2" , distributorRelationMapper.getB2ByUid(user.getUid() ,1));
        nowBrokeragePrice.put("b3" , distributorRelationMapper.getB2ByUid(user.getUid() ,2));
        nowBrokeragePrice.put("b4" , distributorRelationMapper.getB2ByUid(user.getUid() ,3));

        nowBrokeragePrice.put("c1" , distributorRelationMapper.getC3ByUid(user.getUid()));
        nowBrokeragePrice.put("c2" , distributorRelationMapper.getC2ByUid(user.getUid() ,1));
        nowBrokeragePrice.put("c3" , distributorRelationMapper.getC2ByUid(user.getUid() ,2));
        nowBrokeragePrice.put("c4" , distributorRelationMapper.getC2ByUid(user.getUid() ,3));
        return ApiResult.ok(nowBrokeragePrice);
    }

    @AuthCheck
    @GetMapping("/user/brokerageDetails")
    @ApiOperation(value = "佣金明细",notes = "佣金明细")
    public ApiResult brokerageDetails(@RequestParam(value = "type" ) Integer type,
                                      @RequestParam(value = "page" ,defaultValue = "1") Integer page,
                                      @RequestParam(value = "limit" ,defaultValue = "10") Integer limit){
        YxUser user = LocalUser.getUser();
        Page<BrokerageDetailDto> pageModel = new Page<>(page, limit);
        IPage<BrokerageDetailDto> listDtoIPage = distributorRelationMapper.brokerageDetails(pageModel , user.getUid() , type);
        return ApiResult.ok(listDtoIPage);
    }


    @AuthCheck
    @NoRepeatSubmit
    @GetMapping("/user/transferAccounts")
    @ApiOperation(value = "转账佣金",notes = "转账佣金")
    public ApiResult transferAccounts(@RequestParam(value = "phone") String  phone ,
                                      @RequestParam(value = "realName") String realName ,
                                      @RequestParam(value = "number") BigDecimal number ,
                                      @RequestParam(value = "psd") String  psd){
        YxUser user = LocalUser.getUser();
        if(ObjectUtil.isEmpty(phone) || ObjectUtil.isEmpty(number) || ObjectUtil.isEmpty(psd)) throw new YshopException("参数错误");
        Optional.ofNullable(user.getPayPassword()).orElseThrow(()->new YshopException("请设置支付密码"));
        if(!user.getPayPassword().equals(SecureUtil.md5(psd))) throw new YshopException("支付密码错误");
        if(user.getBrokeragePrice().compareTo(number)  == -1) throw new YshopException("账户佣金不足");
        YxUser user1 = yxUserService.getOne(new QueryWrapper<YxUser>().lambda().eq(YxUser::getPhone, phone));
        Optional.ofNullable(user1).orElseThrow(()->new YshopException("转账用户不存在"));
        if(user.getPhone().equals(phone)) throw new YshopException("转账用户为自己");

        YxAuthentication authentication = authenticationService.getOne(new QueryWrapper<YxAuthentication>().lambda().eq(YxAuthentication::getUid, user1.getUid()));
        if (ObjectUtil.isEmpty(authentication)) throw new YshopException("当前用户未实名！");
        if (!authentication.getRealName().equals(realName)) throw new YshopException("转账用户实名错误！");

        //转账用户
        BigDecimal up1 = user.getBrokeragePrice().subtract(number).setScale(2, BigDecimal.ROUND_HALF_UP);
        YxUserBill userBill = YxUserBill.builder()
            .uid(user.getUid())
            .title("佣金转账至用户——"+phone)
            .category(BillDetailEnum.CATEGORY_4.getValue())
            .type(BillDetailEnum.TYPE_13.getValue())
            .number(number)
            .balance(up1)
            .mark("佣金转账至用户——"+phone)
            .payType(3)
            .status(BillEnum.STATUS_1.getValue())
            .pm(BillEnum.PM_0.getValue())
            .build();
        user.setBrokeragePrice(up1);
        yxUserService.updateById(user);
        userBillService.save(userBill);

        //收入用户
        BigDecimal up2 = user1.getBrokeragePrice().add(number).setScale(2, BigDecimal.ROUND_HALF_UP);
        YxUserBill userBill1 = YxUserBill.builder()
                .uid(user1.getUid())
                .title("收到用户——"+user.getPhone()+"佣金转账")
                .category(BillDetailEnum.CATEGORY_4.getValue())
                .type(BillDetailEnum.TYPE_13.getValue())
                .number(number)
                .balance(up2)
                .mark("收到用户——"+user.getPhone()+"佣金转账")
                .payType(3)
                .status(BillEnum.STATUS_1.getValue())
                .pm(BillEnum.PM_1.getValue())
                .build();
        user1.setBrokeragePrice(up2);
        yxUserService.updateById(user1);
        userBillService.save(userBill1);

        return ApiResult.ok("转账成功");
    }



    @AuthCheck
    @NoRepeatSubmit
    @GetMapping("/user/transferPriceAccounts")
    @ApiOperation(value = "转账余额",notes = "转账余额")
    public ApiResult transferPriceAccounts(@RequestParam(value = "phone") String  phone ,
                                      @RequestParam(value = "number") BigDecimal number ,
                                      @RequestParam(value = "psd") String  psd){
        YxUser user = LocalUser.getUser();
        //判断是否是10的倍数
        BigDecimal dividePrice = number.divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
        if (new BigDecimal(dividePrice.intValue()).compareTo(dividePrice) != 0) throw new YshopException("转账手续费必须是100的倍数");

        if(ObjectUtil.isEmpty(phone) || ObjectUtil.isEmpty(number) || ObjectUtil.isEmpty(psd)) throw new YshopException("参数错误");
        Optional.ofNullable(user.getPayPassword()).orElseThrow(()->new YshopException("请设置支付密码"));
        if(!user.getPayPassword().equals(SecureUtil.md5(psd))) throw new YshopException("支付密码错误");
        BigDecimal nowMoney = new BigDecimal(String.valueOf(redisUtil.get("UserPrice" + user.getUid())));
        if(nowMoney.compareTo(number)  == -1) throw new YshopException("账户手续费不足");
        YxUser user1 = yxUserService.getOne(new QueryWrapper<YxUser>().lambda().eq(YxUser::getPhone, phone));
        Optional.ofNullable(user1).orElseThrow(()->new YshopException("转账用户不存在"));
        if(user.getPhone().equals(phone)) throw new YshopException("转账用户为自己");
        //只可为直推
        YxDistributorRelation distributorRelation = distributorRelationMapper.selectOne(new QueryWrapper<YxDistributorRelation>().lambda()
                .eq(YxDistributorRelation::getUid, user1.getUid()));
        if (ObjectUtil.isEmpty(distributorRelation) || distributorRelation.getPUid().longValue() != user.getUid().longValue()){
            throw new YshopException("转账用户必须是直推!");
        }

        //转账用户
        BigDecimal up1 = nowMoney.subtract(number).setScale(2, BigDecimal.ROUND_HALF_UP);
        YxUserBill userBill = YxUserBill.builder()
                .uid(user.getUid())
                .title("手续费转账至用户——"+phone)
                .category(BillDetailEnum.CATEGORY_1.getValue())
                .type(BillDetailEnum.TYPE_13.getValue())
                .number(number)
                .balance(up1)
                .mark("手续费转账至用户——"+phone)
                .payType(3)
                .status(BillEnum.STATUS_1.getValue())
                .pm(BillEnum.PM_0.getValue())
                .build();
        user.setNowMoney(up1);
        yxUserService.updateById(user);
        userBillService.save(userBill);
        //修改redis
        redisUtil.set("UserPrice"+user.getUid() , up1);

        //收入用户
        BigDecimal user1Price = new BigDecimal(String.valueOf(redisUtil.get("UserPrice" + user1.getUid())));
        BigDecimal up2 = user1Price.add(number).setScale(2, BigDecimal.ROUND_HALF_UP);
        YxUserBill userBill1 = YxUserBill.builder()
                .uid(user1.getUid())
                .title("收到用户——"+user.getPhone()+"手续费转账")
                .category(BillDetailEnum.CATEGORY_1.getValue())
                .type(BillDetailEnum.TYPE_13.getValue())
                .number(number)
                .balance(up2)
                .mark("收到用户——"+user.getPhone()+"手续费转账")
                .payType(3)
                .status(BillEnum.STATUS_1.getValue())
                .pm(BillEnum.PM_1.getValue())
                .build();
        user1.setNowMoney(up2);
        yxUserService.updateById(user1);
        userBillService.save(userBill1);
        //修改redis
        redisUtil.set("UserPrice"+user1.getUid() , up2);

        return ApiResult.ok("转账成功");
    }

    @AuthCheck
    @GetMapping("/user/myEarnings")
    @ApiOperation(value = "我的收益",notes = "我的收益")
    public ApiResult transferAccounts(@RequestParam(value = "page" ,defaultValue = "1") Integer page,
                                      @RequestParam(value = "limit" ,defaultValue = "10") Integer limit){
        YxUser user = LocalUser.getUser();
        Map<String , Object> hashMap = new HashMap();
        //个人收益
        BigDecimal userEarnings = distributorRelationMapper.getB1ByUid(user.getUid());
        hashMap.put("userEarnings" ,userEarnings );
        BigDecimal userEarnings1 = distributorRelationMapper.getB5ByUid(user.getUid());
        hashMap.put("userNowEarnings" ,userEarnings1);
        BigDecimal userOldEarnings = distributorRelationMapper.getB6ByUid(user.getUid());
        hashMap.put("userOldEarnings" ,userOldEarnings);
        //收益明细
        Page<BrokerageDetailDto> pageModel = new Page<>(page, limit);
        IPage<BrokerageDetailDto> earningsList = distributorRelationMapper.getEarningsList(pageModel, user.getUid());
        hashMap.put("earningsList" , earningsList);
        return ApiResult.ok(hashMap);
    }

    @GetMapping("/productList")
    @ApiOperation(value = "积分商品列表",notes = "积分商品列表")
    public ApiResult productList(@RequestParam(value = "page" ,defaultValue = "1") Integer page,
                                 @RequestParam(value = "limit" ,defaultValue = "10") Integer limit){
        Page<AuctionProduct> pageModel = new Page<>(page, limit);
        IPage<AuctionProduct> auctionProductIPage = auctionProductMapper.selectPage(pageModel, new QueryWrapper<AuctionProduct>().lambda()
                .eq(AuctionProduct::getIsDel, CommonEnum.DEL_STATUS_0.getValue())
                .eq(AuctionProduct::getType , 2)
                .eq(AuctionProduct::getIsPay, 0)
                .orderByAsc(AuctionProduct::getSort));
        return ApiResult.ok(auctionProductIPage);
    }


    @AuthCheck
    @GetMapping("/exchangeProduct")
    @NoRepeatSubmit
    @ApiOperation(value = "兑换积分商品",notes = "兑换积分商品")
    public ApiResult exchangeProduct(@RequestParam(value = "pid" ,required = false) Long pid){
        YxUser user = LocalUser.getUser();

        /*YxAppdict productTime = yxAppdictService.findAppdictByCode("exchangeProductTime");
        String startTime = productTime.getMemo().split("~")[0];
        String endTime = productTime.getMemo().split("~")[1];
        Calendar nowTime = Calendar.getInstance();
        Integer hour = nowTime.get(Calendar.HOUR_OF_DAY);
        if (hour < Integer.valueOf(startTime) ) throw new YshopException("未开始，时间："+productTime.getMemo());
        if (hour >= Integer.valueOf(endTime) ) throw new YshopException("已结束，时间："+productTime.getMemo());*/

        AuctionProduct auctionProduct = auctionProductMapper.selectById(pid);
        Optional.ofNullable(auctionProduct).orElseThrow(() -> new YshopException("当前积分商品不存在"));
        if (auctionProduct.getIsPay() == 1) throw new YshopException("当前商品已被兑换");
        if (user.getIntegral().compareTo(auctionProduct.getIntegral()) == -1) throw new YshopException("银锭不足");
        //修改商品状态
        auctionProduct.setIsPay(1);
        auctionProductMapper.updateById(auctionProduct);
        //扣除积分
        BigDecimal subtract = user.getIntegral().subtract(auctionProduct.getIntegral());
        YxUserBill integralBill = YxUserBill.builder()
                .uid(user.getUid())
                .title("购买商品")
                .linkId(auctionProduct.getId().toString())
                .type(BillDetailEnum.TYPE_3.getValue())
                .category(BillDetailEnum.CATEGORY_2.getValue())
                .number(auctionProduct.getIntegral())
                .balance(subtract)
                .mark("购买商品")
                .status(BillEnum.STATUS_1.getValue())
                .pm(BillEnum.PM_0.getValue())
                .build();
        userBillService.save(integralBill);
        user.setIntegral(subtract);
        yxUserService.updateById(user);
        //生成记录
        YxUserGoods userGoods = new YxUserGoods();
        userGoods.setPid(auctionProduct.getId());
        userGoods.setUid(user.getUid());
        userGoods.setStatus(2);
        userGoodsService.save(userGoods);

        //生成抢拍记录
        AuctionRecord auctionRecord = new AuctionRecord();
        Object o = redisUtil.get("dict:sxf");
        Object yj = redisUtil.get("dict:yjbl");
        String[] yjs = String.valueOf(yj).split(",");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE , 1);
        auctionRecord.setStartTime(c.getTime());
        auctionRecord.setUserId(userGoods.getUid().intValue());
        BigDecimal nextPrice =auctionProduct.getPrice().multiply(new BigDecimal(yjs[1])).add(auctionProduct.getPrice());
        auctionRecord.setPrice(nextPrice);
        auctionRecord.setTopPrice(auctionProduct.getTopPrice());
        auctionRecord.setTimeId(auctionProduct.getTimeId());
        auctionRecord.setAuctionProductId(auctionProduct.getId());
        auctionRecord.setServiceCharge(auctionProduct.getPrice().multiply(new BigDecimal(String.valueOf(o))));
        auctionRecordService.save(auctionRecord);
        redisUtil.set("paimai"+auctionRecord.getId(),auctionRecord.getId());
        auctionRecord.setUpId(auctionRecord.getId());
        auctionRecordService.updateById(auctionRecord);

        return ApiResult.ok("兑换成功, 已放置拍卖专区！");
    }


    @AuthCheck
    @GetMapping("/integralProductList")
    @ApiOperation(value = "我的积分商品列表",notes = "我的积分商品列表")
    public ApiResult integralProductList(){
        YxUser user = LocalUser.getUser();
        List<UserGoodsDto> userGoodsDtoIPage = auctionProductMapper.integralProductList(user.getUid());
        return ApiResult.ok(userGoodsDtoIPage);
    }

    @AuthCheck
    @NoRepeatSubmit
    @GetMapping("/useProduct")
    @ApiOperation(value = "使用商品",notes = "使用商品")
    public ApiResult useProduct(@RequestParam(value = "id" , required = false) Long id){
        YxUser user = LocalUser.getUser();
        YxUserGoods userGoods = userGoodsService.getById(id);
        Optional.ofNullable(userGoods).orElseThrow(()-> new YshopException("当前兑换商品不存在"));
        userGoods.setStatus(1);
        userGoodsService.updateById(userGoods);
        return ApiResult.ok("使用成功 ， 待审核！");
    }


    /**
     * 查找用户上级等级
     *
     * @param us 用户id
     *
     */
    public List<Long> getFansNum(String us){
        List<Long> uList = new ArrayList<>();
        List<Long> uList1 = distributorRelationMapper.getUList(us);
        if(ObjectUtil.isNotEmpty(uList1)){
            uList.addAll(uList1);
            List<Long> fansNum = getFansNum(StringUtils.join(uList1, ","));
            uList.addAll(fansNum);
        }
        return uList;
    }

}

